package com.ruoyi.game.core.card;

import com.ruoyi.game.core.GameRoundCore;
import com.ruoyi.game.core.GameRoundPos;
import com.ruoyi.game.core.GameSetCore;
import com.ruoyi.game.core.GameSetPos;
import lombok.extern.slf4j.Slf4j;

import java.util.*;
import java.util.stream.Collectors;

import static com.ruoyi.game.core.card.BasePoker.toCardString;

/**
 * 甩牌（AllShuai）牌型策略
 */
@Slf4j
public class AllShuaiCardTypeImpl extends BaseCardType {

    @Override
    public String getName() {
        return "甩牌";
    }

    @Override
    public List<Integer> firstAutoOut(GameSetPos pos) {
        // ⚠️ 暂不自动甩牌出牌
        log.info("[AllShuai] 玩家 {} 连对自动甩牌，暂不进行首出连对", pos.getPlayerId());
        return Collections.emptyList();
    }

    @Override
    public List<Integer> followAutoOut(GameSetPos pos, GameRoundCore round) {
        if (round == null) return Collections.emptyList();

        GameSetCore set = round.getRoomSet();
        int zhuColor = set.getLiangZhuInfo().getZhuColor();
        int zhuValue = set.getZhuValue();
        int firstOutColor = BasePoker.getCardColor(round.getFirstOutCards().get(0));

        List<Integer> all = pos.getHandCards();
        List<Integer> sameColor = getFollowableCards(pos, round);

        List<List<Integer>> firstOutLianDui = lianDuiList(round.getFirstOutCards(), zhuColor, zhuValue, firstOutColor);
        List<List<Integer>> firstOutDui = findDuiGroups(round.getFirstOutCards(), zhuColor, zhuValue, firstOutColor);
        int targetSize = round.getFirstOutCards().size();
        log.info("[AllShuai] 玩家 {} 自动甩牌策略执行", pos.getPlayerId());
        log.info("[AllShuai] 首出牌组（连对）: {}", BasePoker.toCardStringList(firstOutLianDui));
        log.info("[AllShuai] 首出牌组（对子）: {}", BasePoker.toCardStringList(firstOutDui));
        log.info("[AllShuai] 目标牌数量：{}", targetSize);

        List<Integer> result = new ArrayList<>();
        // 跟甩逻辑：先尝试连对，再尝试对子，再补散牌
        if (!firstOutLianDui.isEmpty()) {
            List<Integer> lianDuiCards = followLianDui(result, sameColor, targetSize, zhuColor, zhuValue, firstOutColor);
            log.info("[AllShuai] 玩家 {} 匹配连对：{}", pos.getPlayerId(), BasePoker.toCardString(lianDuiCards));
            result.addAll(lianDuiCards);
        }

        if (!firstOutDui.isEmpty() || !firstOutLianDui.isEmpty()) {
            List<Integer> duiCards = followDui(result, sameColor, targetSize, zhuColor, zhuValue, firstOutColor);
            log.info("[AllShuai] 玩家 {} 匹配对子：{}", pos.getPlayerId(), BasePoker.toCardString(duiCards));
            result.addAll(duiCards);
        }

        List<Integer> sanPaiSameColor = followSanPai(result, sameColor, targetSize, zhuColor, zhuValue, firstOutColor);
        log.info("[AllShuai] 玩家 {} 补同色散牌（或跟主牌）：{}", pos.getPlayerId(), BasePoker.toCardString(sanPaiSameColor));
        result.addAll(sanPaiSameColor);

        // 第四步：尝试用任意散牌补充至目标数量
        List<Integer> sanPaiAll = followSanPai(result, all, targetSize, zhuColor, zhuValue, firstOutColor);
        log.info("[AllShuai] 玩家 {} 补任意散牌：{}", pos.getPlayerId(), BasePoker.toCardString(sanPaiAll));
        result.addAll(sanPaiAll);

        log.info("[AllShuai] 玩家 {} 自动甩牌最终选择：{}", pos.getPlayerId(), BasePoker.toCardString(result));
        return result;
    }

    private List<List<Integer>> findDuiGroups(List<Integer> cards, int zhuColor, int zhuValue, int targetColor) {
        return duiList(cards, zhuColor, zhuValue, targetColor);
    }

    private List<Integer> followLianDui(List<Integer> existing, List<Integer> candidates, int targetSize, int zhuColor, int zhuValue, int targetColor) {
        List<Integer> copy = new ArrayList<>(existing);
        List<Integer> candidateCopy = new ArrayList<>(candidates); // 防止原列表被改动
        followLianDuiSanPais(copy, candidateCopy, targetSize, zhuColor, zhuValue, targetColor);
        return copy.subList(existing.size(), copy.size()); // 返回本次新增的部分
    }

    private List<Integer> followDui(List<Integer> existing, List<Integer> candidates, int targetSize, int zhuColor, int zhuValue, int targetColor) {
        List<Integer> copy = new ArrayList<>(existing);
        List<Integer> candidateCopy = new ArrayList<>(candidates);
        followDuiSanPais(copy, candidateCopy, targetSize, zhuColor, zhuValue, targetColor);
        return copy.subList(existing.size(), copy.size());
    }

    private List<Integer> followSanPai(List<Integer> existing, List<Integer> candidates, int targetSize,
                                       int zhuColor, int zhuValue, int targetColor) {
        List<Integer> copy = new ArrayList<>(existing);
        followSanPais(copy, candidates, targetSize, zhuColor, zhuValue, targetColor);
        return copy.subList(existing.size(), copy.size());
    }

}
